package com.flower.domain.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.flower.auth.common.enums.AuthUserStatusEnum;
import com.flower.auth.common.enums.IsDeletedFlagEnum;
import com.flower.auth.infra.basic.entity.*;
import com.flower.auth.infra.basic.service.*;
import com.flower.domain.config.RedisUtil;
import com.flower.domain.convert.AuthUserBOConverter;
import com.flower.domain.entity.AuthUserBO;
import com.flower.domain.service.AuthUserDomainService;
import com.google.gson.Gson;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author lavender
 * @version 1.0
 * @date 2024-07-16 21:24
 */
@Service
public class AuthUserDomainServiceImpl implements AuthUserDomainService {

    @Resource
    private AuthUserService authUserService;

    @Resource
    private AuthRoleService authRoleService;


    @Resource
    private AuthUserRoleService authUserRoleService;

    @Resource
    private AuthPermissionService authPermissionService;

    @Resource
    private AuthRolePermissionService authRolePermissionService;

    private String salt  = "life";


    private static final String NORMAL_USER = "normal_user";

    @Resource
    private RedisUtil redisUtil;

    private String authPermissionPrefix = "auth.permission";

    private String authRolePrefix = "auth.role";


    @Override
    public Boolean register(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBOToUser(authUserBO);

       Integer count =  authUserService.queryByConditionCount(authUser);
       if(count > 0){
           return true;
       }
        if(StringUtils.isNotBlank(authUserBO.getPassword())){
            authUser.setPassword(SaSecureUtil.md5BySalt(authUser.getPassword(), salt));
        }
        authUser.setStatus(AuthUserStatusEnum.OPEN.getCode());
        authUser.setIsDelete(IsDeletedFlagEnum.UN_DELETED.getCode());
        Integer result = authUserService.insert(authUser);

        // 建立一个初步的角色的关联
        AuthRole authRole = new AuthRole();
        authRole.setRoleKey(NORMAL_USER);
        AuthRole roleResult = authRoleService.queryByCondition(authRole);
        Long roleId = roleResult.getId();
        Long userId = authUser.getId();
        AuthUserRole authUserRole = new AuthUserRole();
        authUserRole.setUserId(userId);
        authUserRole.setRoleId(roleId);
        authUserRole.setIsDelete(IsDeletedFlagEnum.UN_DELETED.getCode());

        authUserRoleService.insert(authUserRole);


        String roleKey = redisUtil.buildKey(authRolePrefix, authUser.getUserName());
        List<AuthRole> roleList = new LinkedList<>();
        roleList.add(authRole);
        redisUtil.set(roleKey, new Gson().toJson(roleList));

        //权限
        AuthRolePermission authRolePermission = new AuthRolePermission();
        authRolePermission.setRoleId(roleId);
        List<AuthRolePermission> rolePermissionList =  authRolePermissionService.queryByCondition(authRolePermission);

        List<Long> permissionIdList = rolePermissionList.stream().map(AuthRolePermission::getPermissionId).collect(Collectors.toList());

        // 根据roleId查权限
        List<AuthPermission> authPermissions = authPermissionService.queryByRoleList(permissionIdList);

        String permissionKey = redisUtil.buildKey(authPermissionPrefix, authUser.getUserName());

        redisUtil.set(permissionKey, new Gson().toJson(authPermissions));


        return result > 0;

    }

    @Override
    public Boolean update(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBOToUser(authUserBO);
        Integer result = authUserService.update(authUser);

        return result > 0;
    }

    @Override
    public Boolean delete(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBOToUser(authUserBO);
        authUser.setIsDelete(IsDeletedFlagEnum.DELETE.getCode());
        Integer result = authUserService.update(authUser);

        return result > 0;
    }

    @Override
    public SaTokenInfo deledoLoginte(String validCode) {
        // openId
        String openId = redisUtil.get(validCode);

        AuthUserBO bo = new AuthUserBO();
        bo.setUserName(openId);
        this.register(bo);

        StpUtil.login(openId);
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        return tokenInfo;
    }

    @Override
    public AuthUserBO getUserInfo(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserBOConverter.INSTANCE.convertBOToUser(authUserBO);
        AuthUser userInfo = authUserService.getUserInfo(authUser);

        AuthUserBO UserBO = AuthUserBOConverter.INSTANCE.convertUserToBO(userInfo);
        return UserBO;
    }
}
